<%@ WebHandler Language="C#" Class="GoogleSiteMapHandler" %>
using System;
using System.Collections.Generic;
using CommunityServer.Blogs.Components;
using CommunityServer.Components;
using CommunityServer.Discussions.Components;
using CommunityServer.MediaGalleries.Components;

 public class GoogleSiteMapHandler : BaseSyndicationHandler
    {
		protected override string BaseUrl
		{
			get
			{
				return Globals.HostPath(Context.Request.Url);
			}
		}


		private Section currentSection = null;
		protected override Section GetCurrentSection
		{
			get
			{

				if(currentSection == null)
				{
                    string appType = Context.Request.QueryString["appType"];
                    if (appType == null)
                        throw new Exception("No Application Type");
				    
                    CSContext csContext = CSContext.Current;

				    switch(appType.ToLower())
					{
						case "forum":
                            currentSection = Forums.GetForum(csContext.SectionID, true, false);
							break;

						case "blog":
                            currentSection = Weblogs.GetWeblog(csContext.ApplicationKey);
							break;

						case "media":
                            currentSection = CommunityServer.MediaGalleries.Components.MediaGalleries.GetMediaGallery(csContext.ApplicationKey);
							break;
					    default:
                            throw new Exception("No Application Type Match");
						
					}

                    Permissions.AccessCheck(currentSection, Permission.View, csContext.User);
				    
				}

				return currentSection;
			}
		}

 
		protected override int CacheTime
		{
			get { throw new NotImplementedException(); }
		}

		protected override string CacheKey
		{
			get { throw new NotImplementedException(); }
		}

		protected override bool FeedIsCacheable
		{
			get { return false; }
		}


		protected override CachedFeed BuildFeed()
		{
			BaseSyndicationWriter writer;
            List<GoogleSiteMapItem> items = new List<GoogleSiteMapItem>();

			if(GetCurrentSection != null)
				items.AddRange(BuildURLList(GetCurrentSection));
			
			writer = new GoogeSiteMapWriter(items, new List<Post>(), null, BaseUrl); 
            
			return new CachedFeed(DateTime.Now,null,writer.GetXml());

		}

        private List<GoogleSiteMapItem> BuildURLList(Section section)
    	{
            if (section == null)
                throw new Exception("No Section Defined");

            if(section is Weblog)
			{
				return BuildURLList((Weblog)section);
			}
			else if(section is Forum)
			{
				return BuildURLList((Forum)section);
			}
			else if(section is MediaGallery)
			{
                return BuildURLList((MediaGallery)section);
			}

            return new List<GoogleSiteMapItem>();
		}

     private List<GoogleSiteMapItem> BuildURLList(MediaGallery mg)
		{
            MediaGalleryUrls siteUrls = MediaGalleryUrls.Instance();
            List<GoogleSiteMapItem> items = new List<GoogleSiteMapItem>();
            //build an entry for each picure category
            foreach (PostCategory pc in PostCategories.GetCategories(mg.SectionID, true, false))
			{
                string loc = siteUrls.TagsBrowser(mg.ApplicationKey, new string[] { pc.Name });
				DateTime lastmod = pc.MostRecentSubPostDate;
                items.Add(new GoogleSiteMapItem(loc, lastmod));
			}

			//build an entry for each picutre
            MediaGalleryThreadQuery query = CreateQuery(mg);
			foreach(MediaGalleryPost p in MediaGalleryPosts.GetMediaGalleryPosts(query).Threads)
			{
                string loc = siteUrls.ViewMediaGalleryPost(mg.ApplicationKey, p.ThreadID);
				DateTime lastmod = p.ThreadDate;
                items.Add(new GoogleSiteMapItem(loc, lastmod));
			}

            return items;
		}

        private List<GoogleSiteMapItem> BuildURLList(Weblog w)
		{
			BlogUrls siteUrls = BlogUrls.Instance();

            List<GoogleSiteMapItem> items = new List<GoogleSiteMapItem>();
            foreach (PostCategory pc in PostCategories.GetCategories(w.SectionID, true, false))
			{
				string loc = siteUrls.TagsBrowser(w.ApplicationKey, new string[] { pc.Name });
				// DateTime lastmod = pc.MostRecentSubPostDate;
				
				// *** jknight fix for returning incorrect category modified date
				//
				DateTime lastmod = pc.MostRecentPostDate;
                items.Add(new GoogleSiteMapItem(loc, lastmod));
			}
		
			BlogThreadQuery query;
			//build an entry for each post archive item
			query = CreateQuery(w, BlogPostType.Post);
			foreach(Post p in WeblogPosts.GetBlogThreads(query,true).Threads)
			{
				string loc = siteUrls.Post(p as WeblogPost);
				DateTime lastmod = p.ThreadDate;
                items.Add(new GoogleSiteMapItem(loc, lastmod));
			}

			//build an entry for each article arcive item
			query = CreateQuery(w, BlogPostType.Article);
			foreach(Post p in WeblogPosts.GetBlogThreads(query,true).Threads)
			{
				string loc = siteUrls.Post(p as WeblogPost);
				DateTime lastmod = p.ThreadDate;
                items.Add(new GoogleSiteMapItem(loc, lastmod));
			}


            return items;
		}
        private List<GoogleSiteMapItem> BuildURLList(Forum f)
		{
            ForumThreadQuery query = CreateQuery(f);

            List<GoogleSiteMapItem> items = new List<GoogleSiteMapItem>();
            //build an entry for each post/tread
			//ThreadSet threads = Threads.GetThreads(f.SectionID, 0, 2147483646, CSContext.Current.User, DateTime.MinValue, SortThreadsBy.LastPost, SortOrder.Descending, ThreadStatus.NotSet, ThreadUsersFilter.All, true, false, false, true);
			ThreadSet threads = Threads.GetThreads(query);
			foreach(ForumPost p in threads.Threads)
			{
                //string loc = (p.PostLevel == 1) ? SiteUrls.Instance().Post(p.PostID) : ForumUrls.Instance().PostInPage(p.ParentID, p.PostID);
                string loc = ForumUrls.Instance().PostPermaLink(p.ThreadID, p.PostID);
			    
				DateTime lastmod = p.ThreadDate;
				
				//fix for thread query not supporting IsApproved flag
				if(p.IsApproved)
                    items.Add(new GoogleSiteMapItem(loc, lastmod));
			}
            return items;
		}

		protected virtual BlogThreadQuery CreateQuery(Weblog w, BlogPostType postType)
		{
			BlogThreadQuery query = new BlogThreadQuery();
			query.BlogPostType = postType;
			query.SectionID = w.SectionID;
			query.IncludeCategories = false;
			query.PageIndex = 0;
			// query.PageSize = WeblogConfiguration.Instance().IndividualPostCount;
			
			// *** jknight fix for returning incorrect post count
			//
			if (postType == BlogPostType.Article)
				query.PageSize = w.ArticleCount;
			else 
				query.PageSize = w.PostCount;
			query.SortBy = BlogThreadSortBy.MostRecent;
			query.SortOrder = SortOrder.Descending;
			query.PublishedFilter = BlogPostPublishedFilter.Published;
			query.RequireSectionIsActive = true;

			return query;
		}

        protected virtual MediaGalleryThreadQuery CreateQuery(MediaGallery mg)
		{
            MediaGalleryThreadQuery query = new MediaGalleryThreadQuery();
            query.SectionID = mg.SectionID;

			query.SortBy = MediaGalleryPostSortBy.PostDate; //we should really sort by threaddate (otherwise only the first 1000 will show up on google)

			query.SortOrder = SortOrder.Descending;

			query.RequireSectionIsActive = true;
			query.OnlyApproved = true;

			return query;
		}
        protected virtual ForumThreadQuery CreateQuery(Forum f)
        {
            ForumThreadQuery query = new ForumThreadQuery();
            query.ForumID = f.SectionID;
            query.PageIndex = 0;
            query.PageSize = 2147483646;
            query.SortBy = SortThreadsBy.LastPost;
            query.Order = SortOrder.Descending;
            query.Status = ThreadStatus.NotSet;
            query.UserFilter = ThreadUsersFilter.All;

            return query;
        }
		
	}
